package xyz.chaobei.mall.common.config;

import org.springframework.context.annotation.Bean;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import xyz.chaobei.mall.common.domain.SwaggerProperties;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @copyright (C), 2015-2020
 * @fileName: BaseSwaggerConfig
 * @author: MRC
 * @date: 2020/10/11 21:17
 * @description: 创建Swagger 基础配置
 */
public abstract class BaseSwaggerConfig {

    @Bean
    public Docket createDocket() {
        // 获取自定义配置
        SwaggerProperties properties = this.customSwagger();

        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                // api 生成基本信息
                .apiInfo(this.buildApiInfo(properties))
                // 开启一个端点
                .select()
                // 生成API 的包路径
                .apis(RequestHandlerSelectors.basePackage(properties.getApiBasePackage()))
                // 路径选择
                .paths(PathSelectors.any())
                .build()
                .securitySchemes(buildSecuritySchemes())
                .securityContexts(buildSecurityContext());
        return docket;
    }

    /**
     * <p>自定义请求头
     * <p>author: <a href='mailto:maruichao52@gmail.com'>MRC</a>
     *
     * @return java.util.List<springfox.documentation.service.ApiKey>
     * @since 2021/1/12
     **/
    public List<ApiKey> buildSecuritySchemes() {

        List<ApiKey> apiKeys = new ArrayList<>();

        ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");
        apiKeys.add(apiKey);

        return apiKeys;
    }

    /**
     * 构建API 信息方法，通过自定义的SwaggerProperties 转化为 ApiInfo
     * 通过ApiInfoBuilder 构建一个api信息。
     *
     * @param properties 自定义信息
     * @return
     */
    private ApiInfo buildApiInfo(SwaggerProperties properties) {
        return new ApiInfoBuilder()
                // 标题
                .title(properties.getTitle())
                // 描述
                .description(properties.getDescription())
                // 联系人信息
                .contact(new Contact(properties.getContactName(), properties.getContactUrl(), properties.getContactEmail()))
                // 版本信息
                .version(properties.getVersion())
                .build();
    }

    /**
     * 自定义实现配置信息
     *
     * @return
     */
    public abstract SwaggerProperties customSwagger();

    public List<SecurityContext> buildSecurityContext() {

        List<SecurityContext> list = new LinkedList<>();
        list.add(buildContext("/umsAdmin/.*"));
        list.add(buildContext("/umsRole/.*"));
        list.add(buildContext("/umsMenu/.*"));

        return list;
    }

    private List<SecurityReference> defaultAuth() {
        List<SecurityReference> result = new ArrayList<>();
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        result.add(new SecurityReference("Authorization", authorizationScopes));
        return result;
    }

    private SecurityContext buildContext(String url) {
        return SecurityContext.builder().securityReferences(defaultAuth()).forPaths(PathSelectors.regex(url)).build();
    }

}
